//
//  MaxChangeView.swift
//  Speek
//
//  Created by ZhenyanShan on 2023/7/4.
//

import SwiftUI
import CoreData

struct MaxChangedBill{
    let year:String
    let month:String
    let type:String
    let changedAmount:Double
    let changedRatio:Double
}

struct MaxChangeView: View{
    @Binding var year : String
    @Binding var month : String
    @Binding var tag: Bool
    
    @State private var maxChangedBill : MaxChangedBill? = nil
    
    @Binding var analysisData: AnalysisData
    
    @Environment(\.managedObjectContext)  var context
    let calendar = Calendar.current
    
    var body: some View{
        
        VStack {
            HStack{
                if tag{
                    Text("本月收入最大变化")
                        .font(.headline)
                }else{
                    Text("本月支出最大变化")
                        .font(.headline)
                }
            }
            .padding(.vertical,15)
            
            if maxChangedBill != nil{
                if maxChangedBill?.changedAmount == 0{
                    if tag{
                        VStack{
                            Text("本月的收入似乎")
                            Text("没什么变化～")
                        }
                        .padding(.top,30)
                        
                    }else{
                        VStack{
                            Text("本月的支出似乎")
                            Text("没什么变化～")
                        }
                        .padding(.top,30)
                    }
                }else{
                    HStack(spacing: 15){
                        Image(maxChangedBill?.type ?? "其他")
                        
                        Text(getInOrOut(tag: tag)+"¥" + String(maxChangedBill?.changedAmount ?? 0))
                            .padding(10)
                            .foregroundColor(maxChangedBill?.changedAmount ?? 0 > 0 ? Color(red: 0, green: 0.725, blue: 0.678) :Color(red:100,green: 0.3412,blue: 0.2))
                            .background(RoundedRectangle(cornerRadius: 10)
                                .stroke(maxChangedBill?.changedAmount ?? 0 > 0 ? Color(red:0,green: 0.725,blue: 0.678).opacity(0.5):Color(red:100,green: 0.3412,blue: 0.2).opacity(0.5), lineWidth: 2))
                    }
                    .padding(.bottom,10)
                    
                    VStack(spacing: 10){
                        if(maxChangedBill?.changedAmount ?? 0 > 0){
                            Text("相较上个月增长")
                                .font(.headline)
                            Text("\(String(format: "%.2f", (maxChangedBill?.changedRatio ?? 0) * 100))%")
                                .font(.headline)
                                .foregroundColor(Color(red:0,green: 0.725,blue: 0.678))
                        }else{
                            Text("相较上个月减少 \(String(format: "%.2f", (maxChangedBill?.changedRatio ?? 0) * 100))%")
                                .font(.headline)
                                .foregroundColor(Color(red:100,green: 0.3412,blue: 0.2))
                        }
                    }
                    .padding(.bottom,10)
                }
            }else{
                VStack{
                    if tag{
                        Text("本月或上个月暂无收入")
                    }else{
                        Text("本月或上个月暂无收入")
                    }
                    Text("快去添加账单吧～")
                }
                .padding(.top,30)

            }
            
            Spacer()
            
        }
        .onAppear(){
            maxChangedBill = getMaxChangedBill(year: year, month: month, tag: tag)
            
            analysisData.maxChangedBill = getMaxChangedBill(year: year, month: month, tag: false) ?? MaxChangedBill(year: year, month: month, type:"" , changedAmount: 0, changedRatio: 0)
        }
        .onChange(of: year, perform: { _ in
            maxChangedBill = getMaxChangedBill(year: year, month: month, tag: tag)
            
            analysisData.maxChangedBill = getMaxChangedBill(year: year, month: month, tag: false) ?? MaxChangedBill(year: year, month: month, type:"" , changedAmount: 0, changedRatio: 0)
        })
        .onChange(of: month, perform: { _ in
            maxChangedBill = getMaxChangedBill(year: year, month: month, tag: tag)
            
            analysisData.maxChangedBill = getMaxChangedBill(year: year, month: month, tag: false) ?? MaxChangedBill(year: year, month: month, type:"" , changedAmount: 0, changedRatio: 0)
        })
        .onChange(of: tag, perform: { _ in
            maxChangedBill = getMaxChangedBill(year: year, month: month, tag: tag)
            
            analysisData.maxChangedBill = getMaxChangedBill(year: year, month: month, tag: false) ?? MaxChangedBill(year: year, month: month, type:"" , changedAmount: 0, changedRatio: 0)
        })
        .frame(width: 195,height: 200)
        .background(Color(red: 0.04, green: 0.09, blue: 0.16).cornerRadius(20))
        .preferredColorScheme(.dark)
        //Spacer() // 添加一个 Spacer 来将内容推到最左侧
        
        
    }
    
    //从tag中获取金额显示的正负
    func getInOrOut(tag:Bool)->String{
        if tag {
            return "+"
        }else{
            return "-"
        }
    }
     
    //获取数据库中最小的日期
     func getMinDate() -> Date? {
        let fetchRequest: NSFetchRequest<NSDictionary> = NSFetchRequest(entityName: "BillDetail")
        
        let expressionDescription = NSExpressionDescription()
        expressionDescription.name = "minDate"
        expressionDescription.expression = NSExpression(forFunction: "min:", arguments: [NSExpression(forKeyPath: "date")])
        expressionDescription.expressionResultType = .dateAttributeType
        
        fetchRequest.resultType = .dictionaryResultType
        fetchRequest.propertiesToFetch = [expressionDescription]
        
        do {
            let results = try context.fetch(fetchRequest)
            if let result = results.first, let minDate = result["minDate"] as? Date {
                return minDate
            }
        } catch {
            print("Error fetching minimum date: \(error)")
        }
        
        return nil
    }

    
    //获取一个存有相同年份/月份的BillDetail数组的数组
     func getMonthlyBills(selectedType: String? = nil) -> [MonthlyBill] {
        guard let minDate = getMinDate() else {
            return []
        }
        
        let calendar = Calendar.current
        var currentDate = minDate
        var monthlyBills: [MonthlyBill] = []

        while currentDate <= Date() {
            
            let year = calendar.component(.year, from: currentDate)
            let month = calendar.component(.month, from: currentDate)
            
            let billDetails = getBillDetails(forYear: year, month: month, withType: selectedType)
            
            if(billDetails.isEmpty == false){
                let monthString = String(month)
                let yearString = String(year)
                let monthlyOutput = getTotalAmount(forYear: year, month: month, tag: false, selectedType: selectedType)
                let monthlyIncome = getTotalAmount(forYear: year, month: month, tag: true, selectedType: selectedType)
                
                let monthlyBill = MonthlyBill(month: monthString, year: yearString, billsArray: billDetails,totalOutput: monthlyOutput,totalIncome: monthlyIncome)
                monthlyBills.append(monthlyBill)
                
                currentDate = calendar.date(byAdding: .month, value: 1, to: currentDate)!
            }else{
                currentDate = calendar.date(byAdding: .month, value: 1, to: currentDate)!
            }
        }
        
        // 按时间从大到小排序数组
        monthlyBills.sort { (bill1, bill2) -> Bool in
            let date1 = calendar.date(from: DateComponents(year: Int(bill1.year), month: Int(bill1.month)))
            let date2 = calendar.date(from: DateComponents(year: Int(bill2.year), month: Int(bill2.month)))
            return date1?.compare(date2!) == .orderedDescending
        }
        return monthlyBills
    }
    
    //获得当月某种类型的金额总和
    func getTotalAmountByType(for billDetails: [BillDetail]) -> Double {
        let totalAmount = billDetails.reduce(0.0) { $0 + ($1.cost ) }
        return totalAmount
    }
    
    //
    func getMaxChangedBill(year:String,month:String,tag: Bool)->MaxChangedBill? {
        let types: [String]
        if tag {
            types = expenseDataPoints
        } else {
            types = incomeDataPoints
        }
        var maxChangedType: String = ""
        var maxChangedValue: Double = 0
        
        var curAmount:Double = 0
        var preAmount:Double = 0
        
        
        var curBills : [BillDetail]
        var preBills : [BillDetail]
 
        
        for index in 0..<types.count {
            let currentType = types[index]
            curBills = getBillDetails(forYear: Int(year) ?? 0, month: Int(month) ?? 0, withType: currentType)
            if Int(month) == 1 {
                preBills = getBillDetails(forYear: (Int(year) ?? 0) - 1, month: 12, withType: currentType)
            } else {
                preBills = getBillDetails(forYear: Int(year) ?? 0, month: (Int(month) ?? 0) - 1, withType: currentType)
            }
            
            // 如果 curBills 或 preBills 为空，则跳过本次循环
               if curBills.isEmpty || preBills.isEmpty {
                   continue
               }
            
            curAmount = getTotalAmountByType(for: curBills)
            preAmount = getTotalAmountByType(for: preBills)
            
            let currentChangedValue = curAmount - preAmount
            
            if abs(currentChangedValue) > abs(maxChangedValue) {
                maxChangedValue = currentChangedValue
                maxChangedType = currentType
            }
        }
        
        let ratio = curAmount/preAmount
        let changedRatio = ratio>1 ? ratio-1 : 1-ratio
        let maxChangedBill = MaxChangedBill(year: year, month: month, type: maxChangedType, changedAmount: maxChangedValue, changedRatio: changedRatio)
        
        return maxChangedBill
    }
 
}


//struct MaxChangeView_Previews: PreviewProvider {
//    static var tag:Bool = false
//    static var previews: some View {
//        MaxChangeView(tag: tag,mostChangedValue: -200,changedRatio: 0.2,type: "娱乐")
//    }
//}

